#include "stdafx.h"
#include "HTTPRequest.h"
#include "HTTPReceive.h"
#include "HTTPCloseEnum.h"
#include "HeaderDef.h"



HTTPRequest::~HTTPRequest()
{
}

HTTPRequest::HTTPRequest(AbstractHTTPServer * server, IOCPNetwork * iocp) :server(server), 
	iocp(iocp),
	timer(true),
	postData(NULL),
	connection(NULL)
{
}


void * HTTPRequest::getConnectionId()
{
	return this->connection;
}

unsigned long HTTPRequest::getTotalRecvBytes()
{
	return this->totalReceiveNumber;
}

std::string HTTPRequest::uri(bool decode)
{
	return std::string();
}

std::string HTTPRequest::field(const char * key)
{
	return std::string();
}

bool HTTPRequest::keepAlive()
{
	return this->getField("Connection :") == std::string("keep-alive");
}

bool HTTPRequest::range(__int64 & from, __int64 & to)
{
	return false;
}

bool HTTPRequest::isValid()
{
	if (this->isHeadReceive)
	{
		if (this->postData)
		{

		}
		else
		{
			return this->contentLengths == 0;
		}
	}
	return false;
}

unsigned long HTTPRequest::headerSize()
{
	return 0;
}

unsigned long HTTPRequest::size()
{
	return 0;
}

unsigned long HTTPRequest::contentLength()
{
	return 0;
}

__int64 HTTPRequest::startTime()
{
	return 0;
}

std::string HTTPRequest::getHeader()
{
	return std::string();
}

size_t HTTPRequest::read(unsigned char * buf, size_t len)
{
	return size_t();
}

bool HTTPRequest::eof()
{
	return false;
}

int HTTPRequest::run(void * connId, void * clientSock, unsigned long timeout)
{
	assert(this->clientSocketBuff == NULL);

	if (this->clientSocketBuff)
	{
		return RE_INTERNAL_ERROR;
	}

	this->clientSocket = clientSock;

	this->clientSocketBuff = new byte[MAX_SOCKET_RECEIVE_BUFF];

	this->clientSocketLength = MAX_SOCKET_RECEIVE_BUFF;

	this->connection = connId;

	//开始接收请求头
	if (IOCP_PENDING == this->iocp->receive(this->clientSocket, this->clientSocketBuff, this->clientSocketLength, timeout, RequestCallBack, this))
	{
		return RE_SUCCESS;
	}
	else
	{
		this->reset();
		return RE_CLIENTCLOSED;
	}

	return 0;
}

bool HTTPRequest::stop(int ec)
{
	return false;
}

bool HTTPRequest::reset()
{
	this->connection = NULL;

	this->clientSocket = NULL;

	delete[] this->clientSocketBuff;

	this->clientSocketBuff = NULL;

	this->clientSocketLength = 0;

	this->isHeadReceive = false;

	this->totalReceiveNumber = 0;

	if (this->postData)
	{
		
		delete this->postData;

		this->postData = NULL;
	}

	this->headerData.trunc();

	return true;
}

/*获取请求方法*/
HTTPMethod HTTPRequest::method()
{
	char tmp[100] = { 0 };

	char buffer = NULL;

	for (size_t i = 0; i < 100; i++)
	{
		buffer = this->headerData.getBuffer()[i];

		if (buffer == ' ') {
			break;
		}
		else
		{
			tmp[i] = buffer;
		}
	}

	// 返回
	if (strcmp(tmp, "GET") == 0) return METHOD_GET;
	if (strcmp(tmp, "PUT") == 0) return METHOD_PUT;
	if (strcmp(tmp, "POST") == 0) return METHOD_POST;
	if (strcmp(tmp, "HEAD") == 0) return METHOD_HEAD;
	if (strcmp(tmp, "DELETE") == 0) return METHOD_DELETE; // 删除
	if (strcmp(tmp, "TRACE") == 0) return METHOD_TRACE;
	if (strcmp(tmp, "CONNECT") == 0) return METHOD_CONNECT;

	return METHOD_UNKNOW;


}

void  HTTPRequest::RequestCallBack(iocpKey k, int flags, bool result, int transfered, byte* buf, size_t len, void* param)
{
	HTTPRequest * request = reinterpret_cast<HTTPRequest*>(param);

	assert(flags & IOCP_RECV);

	request->onRecive(flags, transfered);
}

void HTTPRequest::onRecive(size_t flags, byte lpNumberOfBytesRecvd)
{
	// 接收失败
	if (lpNumberOfBytesRecvd == 0)
	{
		if (flags & IOCP_READTIMEO)
		{
			this->close(RE_RECV_TIMEO);
		}
		else
		{
			this->close(RE_CLIENTCLOSED);
		}
		
		return;
	}

	//记录开始时间
	if (this->starParsetTime == 0)
	{
		this->starParsetTime = this->timer.getNow();
	}

	this->totalReceiveNumber += lpNumberOfBytesRecvd;

	unsigned int bufferUsed = this->push(this->clientSocketBuff, lpNumberOfBytesRecvd);

	// 检测是否有效
	if (this->isValid())
	{
		assert(lpNumberOfBytesRecvd == bufferUsed);


		this->close(RE_SUCCESS);
	}
	else
	{
		if (bufferUsed != lpNumberOfBytesRecvd)
		{
			// 数据 长度溢出/需要给客户端返回 400 错误,所以用 CT_SUCESS 退出码
			this->close(RE_SUCCESS);
		}
		else
		{
			//
			int status = this->iocp->receive(this->clientSocket, this->clientSocketBuff, this->clientSocketLength, 50, RequestCallBack, this);

			if (status != IOCP_PENDING)
			{
				this->close(status == RE_SESSION_TIMEO ? RE_SESSION_TIMEO : RE_CLIENTCLOSED);
			}
		}
	}

}

void HTTPRequest::close(int exitCode)
{
	this->deleteSocketBuff();

	this->server->onRequest(this, exitCode);
}

int HTTPRequest::push(const byte * data, unsigned int len)
{
	if (this->isHeadReceive)
	{
		return 0;
	}
	else
	{
		unsigned int i;

		// 一个一个的写入
		for ( i = 0; i < len; i++)
		{
			if (1 != this->headerData.write(&data[i], 1))
			{
				//缓冲区溢出
				assert(0);
				return 0;
			}

			if (this->headerData.isEnd())
			{

				this->contentLengths = this->getContentLenth();

				if (this->contentLengths > MAX_POST_DATA)
				{
					AfxMessageBox("post 数据超过请求限制");

					return 0;
				}

				//已接收到完整的请求头
				this->isHeadReceive = true;


				if (i < len)
				{
					i += this->push(data + i, len - i);
				}
			}
			
		}
		return i;
	}
}


/*
  获取header 字段值
*/
std::string HTTPRequest::getField(const char *field)
{
	char *p = reinterpret_cast<char*>(this->headerData.getBuffer());

	const char * start = strstr(p, field);

	if (start == NULL)
	{
		return "";
	}

	const char * end = strstr(start, "\r\n");

	if (end == NULL)
	{
		return "";
	}

	const char *value = "";

	std::string header("");

	header.assign(value, end - start);

	std::string tmp(value);

	delete[] value;
	
	delete[] field;

	delete[] start;

	delete[] end;

	return tmp;
}

/*获取请求长度*/
size_t HTTPRequest::getContentLenth()
{
	std::string content = this->getField("Content-Length: ");

	if (content == "" || content.length() == 0)
	{
		return 0;
	}

	return std::stoi(content);
}

void HTTPRequest::deleteSocketBuff()
{
	delete[] this->clientSocketBuff;

	this->clientSocketLength = 0;

	this->clientSocketBuff = NULL;
}

